using AutoMapper;
using SmartLink.Domain.Entity;
using SmartLink.DTOS.SysBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartLink.Infrastructure.Mappers
{
    public static class SysModuleTreeHelper
    {
        public static SysModuleTreeNodeDTO ListToTree(this IEnumerable<SYS_Module> entities)
        {
            var rootNode = new SysModuleTreeNodeDTO { ID = -1, MenuName = "所有" };
            rootNode.SubLinks = entities.ListToMultipleTree().ToList();
            return rootNode;
        }

        public static IList<SysModuleTreeNodeDTO> ListToMultipleTree(this IEnumerable<SYS_Module> entities)
        {
            var roots = entities.Where(a => !a.ParentID.HasValue).OrderBy(a => a.Sort).ToList();
            var treeNodes = Mapper.Map<IList<SysModuleTreeNodeDTO>>(roots);
            var nodeChildren = entities.Where(a => a.ParentID.HasValue).GroupBy(a => a.ParentID.Value)
                .ToDictionary(a => a.Key, a => Mapper.Map<List<SysModuleTreeNodeDTO>>(a.OrderBy(b => b.Sort).ToList()));

            foreach (var rootNode in treeNodes)
            {
                AppendSysModuleTreeChildNodes(rootNode, nodeChildren);
            }
            return treeNodes;
        }

        public static IList<SysModuleDTO> TreeToList(this SysModuleTreeNodeDTO tree)
        {
            IList<SysModuleDTO> list = new List<SysModuleDTO>();
            TreeTiled(tree, ref list);
            return list;
        }

        private static void AppendSysModuleTreeChildNodes(SysModuleTreeNodeDTO node, Dictionary<int, List<SysModuleTreeNodeDTO>> allChildNodes)
        {
            if (allChildNodes.ContainsKey(node.ID))
            {
                node.SubLinks = allChildNodes[node.ID];
                foreach (var child in node.SubLinks)
                {
                    AppendSysModuleTreeChildNodes(child, allChildNodes);
                }
            }
        }

        private static void TreeTiled(this SysModuleTreeNodeDTO node, ref IList<SysModuleDTO> list)
        {
            list.Add(Mapper.Map<SysModuleDTO>(node));
            if (node.SubLinks != null && node.SubLinks.Count > 0)
            {
                foreach (var child in node.SubLinks)
                {
                    child.TreeTiled(ref list);
                }
            }
        }
    }
}
